package de.mnit.basis.daten;

import de.mnit.basis.daten.konstant.ZEICHEN;
import de.mnit.basis.daten.konstant.position.POSITION_H;
import de.mnit.basis.fehler.Fehler;
import de.mnit.basis.fehler.Warnung;

/**
 * @author Michael Nitsche
 * 25.11.2010	Erstellt
 */
public class FormatText {

	public static String folge(char z, int breite) {
		Warnung.wennUeber(10000, breite);
		Fehler.zahl.wenn_ZuKlein(0,breite);
		StringBuffer erg=new StringBuffer();
		for(int i=0; i<breite; i++)
			erg.append(z);
		return erg.toString();
	}

	public static String breite(int breite, String t) {
		return breite(breite,' ',t,POSITION_H.LINKS);
	}

	public static String breite(int breite, char fuellzeichen, String t, POSITION_H a) {
		Fehler.zahl.wenn_ZuKlein(0,breite);
		Fehler.objekt.wenn_Null(t,a);
		if(a==POSITION_H.MITTE)
			Fehler.sonstige.da_ToDo();
		int fehl=breite-t.length();
		if(a==POSITION_H.LINKS)
			if(fehl >= 0)
				t+=folge(fuellzeichen,fehl);
			else
				t=t.substring(0,t.length()+fehl);
		if(a==POSITION_H.RECHTS)
			if(fehl >= 0)
				t=folge(fuellzeichen,fehl)+t;
			else
				t=t.substring((-fehl)-1,t.length());
		return t;
	}

	public static String laenge(int laenge, String t) {
		return laenge>=0
			? breite(laenge,' ',t,POSITION_H.LINKS)
			: breite(Math.abs(laenge),' ',t,POSITION_H.RECHTS);
	}

	public static String einfuegen(String das, int pos, String in) {
		Fehler.objekt.wenn_Null(das,in);
		Fehler.zahl.wenn_InListe(pos,0);
		Fehler.zahl.wenn_Ausserhalb(in.length()+1, pos);
		if(pos<0)
			pos = in.length()+pos+1;
		else
			pos--;
		return in.substring(0,pos) + das + in.substring(pos);
	}

	/**
	 *	null hat hier wegen "IS NULL" und "= NULL" nix zu suchen!
	 **/
	private static String zuDB_Befehl(String t) {
		Fehler.objekt.wenn_Null(t);
//		t=FilterText.nicht("^".toCharArray(), t); //Ist innerhalb von '' ok!
		t=t.replaceAll("'", "''"); //TODO Testen! //Das verdoppeln sollte das Zeichen erhalten und gültig machen. " sollten innerhalb von '' kein Problem darstellen
		return t;
	}

	public static String zuDB_Text(String t) {
		return "'"+zuDB_Befehl(t)+"'";
	}

	public static String zuDB_Bezeichner(String t) {
		Fehler.objekt.wenn_Null(t);
		// Nicht nur uppercase, MySql ist z.B. case-sensitive!
		return FilterText.nur((ZEICHEN.ABC+ZEICHEN.ABC.toUpperCase()+"_").toCharArray(), t);
	}

	public static String zuDateiname(String t) {
		Fehler.objekt.wenn_Null(t);
		String erlaubt=
			ZEICHEN.DEUTSCH.toUpperCase()
			+ZEICHEN.DEUTSCH.toLowerCase()
			+ZEICHEN.DEZIMAL +"_- #.,'(){}[]&"; //TODO Erweitern!!!
		return FilterText.nur(erlaubt.toCharArray(), t);
	}

	public static String ersterBuchstabeGross(String text) {
		char[] ca=text.toCharArray();
		char letzter=' ';
		int pos=0;
		while(pos>=0 && pos<ca.length) {
			Character aktuell=ca[pos];
			if(Character.isLetter(aktuell) && !Character.isLetter(letzter))
				ca[pos]=Character.toUpperCase(ca[pos]);

			pos++;
			letzter=aktuell;
		}
		return new String(ca);
	}

	public static String zuHTMLZeichen(String s) {
		s=s.replaceAll("&", "&amp;"); // Muss extra und als erstes erfolgen!!!
		for(HTML_ZEICHEN hz : HTML_ZEICHEN.values())
			s=s.replaceAll(""+hz.zeichen, hz.html);
		return s;
	}

	public static String vonHTMLZeichen(String s) {
		for(HTML_ZEICHEN hz : HTML_ZEICHEN.values())
			s=s.replaceAll(hz.html, ""+hz.zeichen);
		s=s.replaceAll("&amp;", "&"); // Muss extra und als letztes erfolgen!!!
		return s;
	}

	/**
	 * Ersetzt Platzhalter in einem Template durch Werte.
	 * %a 	>	werte[0]
	 * %b	>	werte[1]
	 * ...
	 *
	 * Nicht vergleichbar mit String.format, da hier ein Platzhalter auch mehrfach verwendet werden kann!
	 */
	public static String fuellen(String template, String... werte) {
		Fehler.objekt.wenn_Null(template, werte);
		Fehler.bereich.wenn_ElementNull(werte);
		Fehler.zahl.wenn_ZuGross(27, werte.length);
		for(int i=0; i<werte.length; i++) {
			String suche="%"+ZEICHEN.ABC.charAt(i);
			template=template.replaceAll(suche, werte[i]);
		}
		return template;
	}

	/**
	 * Wenn der Text länger als der angegebene Wert ist, wird er so gekürzt
	 * und Abschluss angehängt, dass er genau "laengeMax" Zeichen hat.
	 * Ist der Text kürzer oder gleich "laengeMax", wird "abschluss" ignoriert!
	 *
	 * Beispiel:
	 * "testtesttest"	, 10, "..."	> "testtes..."
	 * "testtest"		, 10, "..."	> "testtest"
	 */
	public static String maximal(String text, int laengeMax, String abschluss) {
		Fehler.zahl.wenn_ZuKlein(abschluss.length(), laengeMax);
		if(text.length() <= laengeMax)
			return text;
		return FilterText.teil(laengeMax-abschluss.length(), true, text)+abschluss;
	}

	// INTERN

	private static enum HTML_ZEICHEN {
		auml	('ä', "&auml;"),
		ouml	('ö', "&ouml;"),
		uuml	('ü', "&uuml;"),
		Auml	('Ä', "&Auml;"),
		Ouml	('Ö', "&Ouml;"),
		Uuml	('Ü', "&Uuml;"),
		szlig	('ß', "&szlig;"),
		nbsp	(' ', "&nbsp;"),
		euro	('€', "&euro;"),
		lt		('<', "&lt;"),
		gt		('>', "&gt;");

		private char zeichen;
		private String html;

		private HTML_ZEICHEN(char c, String html) {
			this.zeichen=c;
			this.html=html;
		}
	}

}
